package cn.test.my.jiami;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *  签名工具类
 *
 * @Email: chens@namek.com.cn
 * @Date: 10:57 2020/3/16
 */
public class SignUtils {

    /**
     * 计算签名
     *
     * @param paramMap 需要签名的数据
     * @param appSecret 密钥
     * @return
     */
    public static String countSign(Map<String, Object> paramMap, String appSecret){
        // 将除sign外的所有的参数按照key的ASCII进行排序
        paramMap.remove("sign");
        List<String> keyList = new ArrayList<>(paramMap.size());
        keyList.addAll(paramMap.keySet());
        Collections.sort(keyList);
        // 将所有的参数按照"key=value"的方式使用"&"的方式进行拼接，得到字符串aa
        StringBuilder builder = new StringBuilder();
        for(int i = 0; i < keyList.size(); i++){
            String key = keyList.get(i);
            String value = paramMap.get(key) == null ? "" : paramMap.get(key).toString();
            try {
                // 含有中文的需要进行UTF-8编码
                value = URLEncoder.encode(value, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            builder.append(key).append("=").append(value);
            if(i < keyList.size() - 1){
                builder.append("&");
            }
        }
        // 在aa的后面拼接上appSecret，得到字符串bb，将bb转为小写，得到cc
        String strBeforeEncrypt = builder.toString().concat(appSecret).toLowerCase();
        // 将字符串cc进行md5，得到sign
        String sign = md5(strBeforeEncrypt);
        return sign;
    }

    private static String md5(String str) {
        if(str == null || str.length() == 0) {
            throw new IllegalArgumentException("str is not empty.");
        }
        String newStr = "";
        try {
            // 创建加密对象 并傳入加密类型
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            // 传入要加密的字符串
            messageDigest.update(str.getBytes("UTF-8"));
            // 得到 byte 类型结果
            byte byteBuffer[] = messageDigest.digest();
            // 將 byte 转为 String
            StringBuffer strHexString = new StringBuffer();
            // 遍历 byte buffer
            for (int i = 0; i < byteBuffer.length; i++) {
                String hex = Integer.toHexString(0xff & byteBuffer[i]);
                if (hex.length() == 1) {
                    strHexString.append('0');
                }
                strHexString.append(hex);
            }
            // 得到返回结果
            newStr = strHexString.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return newStr;
    }


	public static void main(String[] args) {
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("aa", 123);
		paramMap.put("appkey", "123456");
		paramMap.put("sign", "1aaaa");
		String sadasdas = countSign(paramMap, "sadasdas");
		System.out.println(sadasdas);
	}

}